home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NetNews Offline 2
/
NetNews Offline Volume 2.iso
/
news
/
comp
/
std
/
c
/
727
< prev
next >
Wrap
Text File
|
1996-08-06
|
6KB
|
148 lines
Path: newshost.uwo.ca!gateway!mail
From: Dave Kinchlea <kinch@julian.uwo.ca>
Newsgroups: comp.std.c
Subject: offsetof() and `address constant expression': LONG
Date: 12 Apr 1996 00:48:08 GMT
Organization: The University of Western Ontario, London, Ont. Canada
Message-ID: <4kk988$rt2@falcon.ccs.uwo.ca>
NNTP-Posting-Host: julian.uwo.ca
X-Date: Thu, 11 Apr 1996 20:48:07 -0400 (EDT)
Originator: daemon@julian.uwo.ca
I think the excellent reply included below from Roger Glover of CRI
(from an original thread in comp.unix.cray) says just about
everything, but for a little more context. I am porting pdksh5.2.4 to
UNICOS and I came across a compiler error that I thought I had
attributed to the following (mis-)defined macro in stddef.h:
#if _RELEASE < 3
#define offsetof(t, memb) ((size_t)__INTADDR__(&(((t *)0)->memb)))
#else
#ifndef __cplusplus
#define offsetof(_TYPE, _MEMBER) _Offsetof(_TYPE, _MEMBER)
#else
#define offsetof(ty,mem) ((size_t)((char *)&(((ty*)0)->mem) - (char *) 0))
#endif
#endif
I conjectured that the #ifndef __cplusplus was meant to be #ifdef (the
compiler version is 4.0), that is the macro that I ended up redefining to
get the code to compile, and appearently work.
Roger makes an excellent case to support the compiler errors, I think
everything hinges on the exact definition of address constant expression.
Plauger says:
An address constant expression specifies a value that has a
pointer type and that the translator or target environment can
determine prior to program startup. Therefore, the epxression must
not cause side effects. ...
Seems pretty clear that the use below does not fit this description but I
would like some confirmation before I send this back to the author. If it
matters, that call is out of an alloc() routine. ICELLS is a macro (100)
and cells is an integer. I think I will let Roger take over ...
On Thu, 11 Apr 1996, Roger Glover wrote:
> Dave:
>
> I took a spare moment to look a this again. Your code line was:
>
> :> bp = (Block*) malloc(offsetof(Block, cell[ICELLS + cells]));
>
> Your error messages were:
>
> :> cc-544 cc: ERROR File = alloc.c, Line = 92
> :> The token "cells" is not valid in a constant expression in this context.
> :> cc-424 cc: ERROR File = alloc.c, Line = 92
> :> The array subscript expression is not a positive integral expression.
> :> cc-477 cc: ERROR File = alloc.c, Line = 92
> :> An expression is terminated with ")" instead of ";".
>
> I used the UNICOS "explain" command to look at these messages in more
> detail. Here is what I got for the first message:
>
> $ explain cc-544
>
> CC_ERROR: The token "token" is not valid in a constant expression in this
> context.
>
> The specified token, while valid within some constant expressions, is not
> valid within a constant expression used to specify the size of a bit field
> member, the value of an enumeration constant, or the value of a case
> constant. Remove the indicated operator from the constant expression.
>
> Not particularly instructive, but the second message cleared things
> up a bit:
>
> $ explain cc-424
>
> CC_ERROR: The array subscript expression is not a positive integral
> expression.
>
> The expression that specifies the subscript of an array within an offsetof
> macro must be an integral constant expression that has a value greater than
> ^^^^^^^^ [[ my emphasis - rg ]]
> zero. Either the subscript specified is not an integral constant expression
> or its value is less than or equal to 0.
>
> It clear that the subscript expression (ICELLS + cells) is not
> constant because the variable "cells" is not constant. The
> straightforward macro that you are suggesting is the correct one:
>
> #define offsetof(ty,mem) ((size_t)((char *)&(((ty*)0)->mem) - (char *) 0))
>
> does not do any integrity checking of the second argument, whereas
> the one you are suggesting is wrong:
>
> #define offsetof(_TYPE, _MEMBER) _Offsetof(_TYPE, _MEMBER)
>
> apparently does perform integrity checking.
>
> The question remains: Is the integrity check correct? Well, the fact
> that the error message is cc-424 (indicating the C compiler rather
> ^^
> than the C++ compiler) shows me that the integrity check is
> intentionally associated with C rather than C++. So I turned to the
> standards (more or less). Plauger and Brodie's "Standard C Quick
> Reference" (ISBN: 1-55615-158-6), which is a concise interpretation
> of the ANSI/ISO C standard, says the following about the "offsetof"
> macro:
> offsetof
> #define offsetof(s-type,mbr) <size_t constant expression>
> The macro yields the offset in bytes of member mbr from the beginning
> of structure type s-type, where for X of type s-type, &X.mbr is an
> address constant expression.
> ^^^^^^^^
>
> Well let's break that down a bit. &X.mbr must be constant, so that
> implies that both X must represent fixed locations and mbr must
> represent a fixed offset from that location. In your case, mbr is
> "cell[ICELLS + cells]", which does not represent a fixed offset,
> since "cells" can vary.
>
> Now one more question remains: Why doesn't C++ have the same
> integrity check? I don't know. As far as I can tell, the C++ draft
> standard subsumes stddef.h, "as is" from ANSI/ISO C. Perhaps their
> is an implementation dependency related to our C++ compiler, but I
> can't tell.
>
> In any case, I do not think the behavior you described is a bug.
>
> ----------------------------------------------- Roger Glover
> XXXX\ \ / \ /XXX \ / \ X \ /\\\ X///X /\\\ Cray Research, Inc.
> / \ / \/ /\ / \ / \X /\ X \ / \ X\ \ X DISCLAIMER HAIKU:
> //X/ X\\\X //X/ X \ X X\\ / \ X/X \ X \\\ C R I may not
> / \ X///X / \/ X//XX X \ / \ X \\ X \ Share these opinions with me
> / \ X X /\\\/ X X X///X /XXX/ X///X /XXX/ This is not my fault
> ----------------------------------------------- http://www.cray.com/education
kinch <finger kinch@julian.uwo.ca> for PGP key(s)
email:kinch@julian.uwo.ca web:http://www.heartlab.rri.uwo.ca/kinch/
Unix PGP Key fingerprint = 6F 36 6F 9D 79 16 DF 40 2B EC 18 5B 5C 6D 03 6F
Home PGP Key fingerprint = 28 20 0E DF 27 17 80 C5 5D 04 8E 1B D0 9A A6 4C